package com.iwhalecloud.bss.kite.cucc.service.scene.attr;

import com.iwhalecloud.bss.kite.client.dto.spec.ObjAttrRstrRulDTO;
import com.iwhalecloud.bss.kite.client.enums.Endpoint;
import com.iwhalecloud.bss.kite.client.vo.scene.ProdAttrModuleVO;
import com.iwhalecloud.bss.kite.client.vo.scene.ProdAttrVO;
import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.constant.SymbolConsts;
import com.iwhalecloud.bss.kite.common.util.KiteBeanUtils;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteMapUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.service.attr.LocalAttrHelper;
import com.iwhalecloud.bss.kite.cucc.service.util.CalculatePkgUsageUtil;
import com.iwhalecloud.bss.kite.cucc.service.util.ProdCateUtil;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferCache;
import com.iwhalecloud.bss.kite.dataservice.cache.ProdAttrRstrRulCache;
import com.iwhalecloud.bss.kite.dataservice.cache.ServiceControlScopeCache;
import com.iwhalecloud.bss.kite.dataservice.entity.DcPublic;
import com.iwhalecloud.bss.kite.dataservice.entity.ServiceControlScope;
import com.iwhalecloud.bss.kite.enums.ObjAttrLinkageType;
import com.iwhalecloud.bss.kite.listener.handler.attr.bo.AttrLinkageSource;
import com.iwhalecloud.bss.kite.listener.handler.attr.bo.SameProdInstAttrSource;
import com.iwhalecloud.bss.kite.listener.handler.attr.impl.core.GeneralAttrLinkageHandler;
import com.iwhalecloud.bss.kite.manager.api.IOperateSceneInstService;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.iwhalecloud.bss.kite.manager.inst.KiteInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteProdInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.iwhalecloud.bss.kite.service.attr.AttrData;
import com.iwhalecloud.bss.kite.service.attr.IAttrHandler;
import com.iwhalecloud.bss.kite.service.attr.handler.DefaultAttrHandler;
import com.iwhalecloud.bss.kite.service.scene.attr.OperateInstAttrService;
import com.ztesoft.bss.base.entity.StaticAttrDO;
import com.ztesoft.bss.common.util.ContextUtil;
import com.ztesoft.bss.common.util.SpringUtil;
import com.ztesoft.zsmart.core.log.ZSmartLogger;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * @author wei.yanhong
 * @ClassName: CuccOperateInstAttrService
 * @Description: 销售品，接入类产品,功能产品属性初始化
 * @date Jun 10, 2019 3:14:32 PM
 */
@Service
public class CuccOperateInstAttrService {
    private static final String ATTR_CLASS_PATH = "com.iwhalecloud.bss.kite.service.attr.handler.DefaultAttrHandler";

    private static final ZSmartLogger LOGGER = ZSmartLogger.getLogger(CuccOperateInstAttrService.class);

    @Autowired
    IOperateSceneInstService operateSceneInstService;

    @Autowired
    IQuerySceneInstService querySceneInstService;

    @Autowired
    private OperateInstAttrService operateInstAttrService;


    private static final AtomicBoolean IF_FALSE = new AtomicBoolean(false);

    private static final AtomicBoolean IF_TRUE = new AtomicBoolean(true);


    /**
     * TODO 获取handlerClass的bean，这里报错就给个DefaultAttrHandler,防止在开发时频繁修改，后面还是要把错抛出去
     *
     * @param handlerClass
     * @return
     */
    @SuppressWarnings("unchecked")
    private IAttrHandler<KiteInst, AttrData> getHandlerClassBean(String handlerClass) {
        IAttrHandler<KiteInst, AttrData> attrHandler;
        try {
            attrHandler = (IAttrHandler<KiteInst, AttrData>) SpringUtil.getOrRegisterBean(Class.forName(handlerClass));
        } catch (ClassNotFoundException e) {
            LOGGER.error(ErrorConsts.CLASS_NOT_FOUND.getMsg(), e);
            // ErrorConsts.ATTR_RULE_CLASS_NOT_FIND_ERROR.throwOut(e, inst.getSpecId(), attr.getFieldName());
            attrHandler = SpringUtil.getOrRegisterBean(DefaultAttrHandler.class);
        }
        return attrHandler;
    }


    /**
     * 对在service_control_scope中配置的需要展示的字段进行处理
     *
     * @param sceneInstId
     * @param custId
     * @param prodInstId
     * @param serviceOfferId
     * @param prodId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ProdAttrModuleVO processAttrs(String sceneInstId, String custId, String prodInstId, String serviceOfferId,
                                         String prodId) {
        ProdAttrModuleVO prodAttrModule = new ProdAttrModuleVO();
        //获取登录员工的省份信息
        String opreatorProvinceNbr= ContextUtil.getLoginInfo().getUserInfo().getPostProvinceNbr();
        // 从中service_control_scope表中查询需要展示的属性
        if (KiteStringUtils.isEmpty(serviceOfferId)) {
            return prodAttrModule;
        }
        List<ServiceControlScope> serviceControlAttrs = ServiceControlScopeCache
            .get(serviceOfferId + SymbolConsts.HYPHEN + prodId);
        Map<String, Object> loginExtParams = ContextUtil.getLoginInfo().getUserInfo().getExtParams();
        String nodeCode = MapUtils.getString(loginExtParams, "nodeCode");
        nodeCode = null == nodeCode ? querySceneInstService.getExtParameterValue(sceneInstId, "nodeCode") : nodeCode;
        String preTaskCode = MapUtils.getString(loginExtParams, "preTaskCode");

        List<ServiceControlScope> haveTacheCode = new ArrayList<>();
        if (null != nodeCode) {
            String finalNodeCode = nodeCode;
            serviceControlAttrs.removeIf(co -> {
                return  !KiteStringUtils.equals(finalNodeCode, co.getTacheCode())&&co.getTacheCode()!=null;
            });
            // 当前环节的配置
            haveTacheCode = serviceControlAttrs.stream().filter(co -> finalNodeCode.equals(co.getTacheCode())).collect(Collectors.toList());
            if (haveTacheCode.size() > 0) {
                List<ServiceControlScope> finalHaveTacheCode = haveTacheCode;
                serviceControlAttrs.removeIf(co -> {
                    ServiceControlScope controlScope = finalHaveTacheCode.stream().filter(sc -> (sc.getFieldName().equals(co.getFieldName()))).findFirst().orElse(null);
                    /**
                     *  1：配置的tache_code为空，取当前同业务同环节的配置
                     *  2：配置的tache_code不为空，取当前同业务同环节的配置
                     *  3：去除不在当前环节的其他属性(tache_code不为空)配置
                     */
                    return (null == controlScope && KiteStringUtils.isNotEmpty(co.getTacheCode()))
                        || (null != controlScope && !KiteStringUtils.equals(controlScope.getTacheCode(), co.getTacheCode()));
                });
            }
        } else if (null == nodeCode) {
            serviceControlAttrs = serviceControlAttrs.stream().filter(co -> null == co.getTacheCode()).collect(Collectors.toList());
        }

        List<ServiceControlScope> allserviceControlAttrs = ServiceControlScopeCache
            .get(serviceOfferId + SymbolConsts.HYPHEN + "1");
        serviceControlAttrs.addAll(allserviceControlAttrs);

        KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
        KiteOfferInst offerInst = querySceneInstService.getOfferInst(custId, sceneInst.getRootInstId());
        String categoryId = OfferCache.get(offerInst.getSpecId()).getCateId();
        List<ServiceControlScope> categoryserviceControlAttrs = ServiceControlScopeCache
            .get(serviceOfferId + SymbolConsts.HYPHEN + categoryId);
        serviceControlAttrs.addAll(categoryserviceControlAttrs);

        // offerId区分，若party_role_id配置offerId，则只取party_role_id=当前offerId，若无，则取party_role_id=null的配置
        String offerId = offerInst.getOfferId();
        boolean ifOfferConfig = serviceControlAttrs.stream().anyMatch(serviceControlScope -> KiteStringUtils.isEqual(offerId, serviceControlScope.getPartyRoleId()));
        if(ifOfferConfig) {
            serviceControlAttrs.removeIf(serviceControlScope -> !KiteStringUtils.isEqual(offerId, serviceControlScope.getPartyRoleId()));
        } else {
            serviceControlAttrs.removeIf(serviceControlScope -> KiteStringUtils.isNotEmpty(serviceControlScope.getPartyRoleId()));
        }

        // 如果service_control_scope中配置的mustEdit为T则将isEdit设置为T
        KiteProdInst inst = querySceneInstService.getProdInst(custId, prodInstId);
        // fieldNameAndIsEdit 为service_control_scope中查出的数据,以FieldName值为key，isEdit值为value,用以记录，为之后取交集和设置是否可以编辑
        //   getKiteInstAttrs(inst, inst.listAttrs(), sceneInst);
        String provinceCode = ContextUtil.getLoginInfo().getUserInfo().getPostProvinceNbr();
        DcPublic mapAidConfig = DcPublicCache.getByPcode("2202241001", "MAP_AID_QRY_BTN", inst.getSpecId()).stream().findFirst().orElse(null);
        Map<String, String> fieldNameAndIsEdit = serviceControlAttrs.stream()
            .collect(Collectors.toMap(ServiceControlScope::getFieldName,
                scope -> Optional.ofNullable(scope.getIsEdit()).orElse("T"), (v1, v2) -> v1));
        /**
         * kiteAttrs是service_control_scope中查出数据对应的属性 过滤思路：
         * inst.listAttrs()是所有属性，fieldNameAndIsEdit为service_control_scope中查出的数据的<fieldName,isEdit>键值对
         * 现只要在service_control_scope中有配置的数据
         */
        List<KiteAttr> kiteAttrs = inst.listAttrs().stream()
            .filter(t -> fieldNameAndIsEdit.containsKey(t.getFieldName())).collect(Collectors.toList());
        if(haveTacheCode.size()>0){
            Map<String, String> fieldNameAndIsEditTache = haveTacheCode.stream()
                .collect(Collectors.toMap(ServiceControlScope::getFieldName,
                    scope -> Optional.ofNullable(scope.getIsEdit()).orElse("T"), (v1, v2) -> v1));
            kiteAttrs = kiteAttrs.stream()
                .filter(t -> fieldNameAndIsEditTache.containsKey(t.getFieldName())).collect(Collectors.toList());
        }
        /**
         * 国际跨域重提2新增逻辑
         */
        if(KiteStringUtils.equals(nodeCode,"OrderResubmit")){
            boolean isModifyFlag = KiteStringUtils.isEqual(sceneInst.getServiceOfferId(), "2826");

            List<DcPublic> dcPublicsCantEdit= DcPublicCache.getByPcode("20211115101", "OrderResubmitTwoNo",offerId);
            //
            if(KiteListUtils.isNotEmpty(dcPublicsCantEdit)){
                Map<String, String> fieldNameAndCantEditTaskCode =new HashMap<>();
                for(DcPublic dcPublic:dcPublicsCantEdit){
                    if(StringUtils.isNotBlank(preTaskCode) && dcPublic.getCodec().contains(preTaskCode)
                        && (KiteStringUtils.isEmpty(dcPublic.getCoded()) || KiteStringUtils.equalsAny(opreatorProvinceNbr, dcPublic.getCoded().split(SymbolConsts.COMMA)))){
                        fieldNameAndCantEditTaskCode.put(dcPublic.getCodea(),dcPublic.getCodeb());
                    }
                }
                if(KiteMapUtils.isNotEmpty(fieldNameAndCantEditTaskCode)){
                    List<KiteAttr> kiteAttrss = inst.listAttrs();
                    for(KiteAttr attr : kiteAttrss){
                        if(!fieldNameAndCantEditTaskCode.containsKey(attr.getFieldName())){
                            attr.setIsEdit(KeyConsts.IFTRUE_F);
                            //避免被scop表配置覆盖
                            if(fieldNameAndIsEdit.containsKey(attr.getFieldName())){
                                fieldNameAndIsEdit.put(attr.getFieldName(),KeyConsts.IFTRUE_F);
                            }
                            if(!isModifyFlag && !kiteAttrs.contains(attr)) {
                                kiteAttrs.add(attr);
                            }
                        }
                    }
                }
            }else {
                List<DcPublic> dcPublicEdit= DcPublicCache.getByPcode("20211115101", "OrderResubmitTwo",offerId);
                if(KiteListUtils.isNotEmpty(dcPublicEdit)){
                    Map<String, String> fieldNameAndIsEditTaskCode =new HashMap<>();
                    for(DcPublic dcPublic:dcPublicEdit){
                        if(StringUtils.isNotBlank(preTaskCode) && dcPublic.getCodec().contains(preTaskCode)
                            && (KiteStringUtils.isEmpty(dcPublic.getCoded()) || KiteStringUtils.equalsAny(opreatorProvinceNbr, dcPublic.getCoded().split(SymbolConsts.COMMA)))){
                            fieldNameAndIsEditTaskCode.put(dcPublic.getCodea(),dcPublic.getCodeb());
                        }
                    }
                    List<KiteAttr> kiteAttrss = inst.listAttrs();
                    for(KiteAttr attr : kiteAttrss){
                        if(fieldNameAndIsEditTaskCode.containsKey(attr.getFieldName())){
                            attr.setIsEdit(KeyConsts.IFTRUE_F);
                            //避免被scop表配置覆盖
                            if(fieldNameAndIsEdit.containsKey(attr.getFieldName())){
                                fieldNameAndIsEdit.put(attr.getFieldName(),KeyConsts.IFTRUE_F);
                            }
                            if(!isModifyFlag && !kiteAttrs.contains(attr)) {
                                // 产品变更，忽略未的配置属性，否则会导致业务变更信息模块显示多余属性
                                kiteAttrs.add(attr);
                            }
                        }
                    }
                }
            }
        }

        List<String> serviceOfferIdList = querySceneInstService.getExtParameterValue(sceneInstId, "BUSI_CHANGE_SERVICEOFFERID");

        /**
         * SDWAN，产品变更-弹性升速，选择操作类型后，不展示的属性无法加载，在此设置属性show_type=H
         */
        if(KiteStringUtils.equals(prodId, "10003406")) {
            if(KiteStringUtils.equalsAny(serviceOfferId, "1051", "1052")) {
                boolean isElastic = KiteStringUtils.equals(serviceOfferId, "1051");
                String showType = isElastic ? KeyConsts.PROD_ATTR_SHOW_TYPE_D : KeyConsts.PROD_ATTR_SHOW_TYPE_H;
                kiteAttrs.forEach(tempAttr -> {
                    tempAttr.setIsNull(KeyConsts.IFTRUE_F);
                    LocalAttrHelper.hiddenOrDisplayProdAttr(sceneInstId, inst, tempAttr, showType, (isElastic ? tempAttr.getValue() : tempAttr.getOriginValue()));
                });
            } else {
                // 非弹性升速，隐藏弹性升速属性
                if(KiteListUtils.isNotEmpty(serviceOfferIdList) && !serviceOfferIdList.contains("1051") && !serviceOfferIdList.contains("1052")) {
                    List<ServiceControlScope> elasticAttrs = ServiceControlScopeCache.get("1051" + SymbolConsts.HYPHEN + categoryId);
                    List<String> fileNameList = new ArrayList<>(elasticAttrs.size());
                    elasticAttrs.forEach(serviceControlScope -> fileNameList.add(serviceControlScope.getFieldName()));
                    inst.listAttrs().forEach(tempAttr -> {
                        if(fileNameList.contains(tempAttr.getFieldName())) {
                            LocalAttrHelper.hiddenOrDisplayProdAttr(sceneInstId, inst, tempAttr, KeyConsts.PROD_ATTR_SHOW_TYPE_E, tempAttr.getOriginValue());
                        }
                    });
                }
            }
        }

        /**
         * 1.假如kiteAttr的isEdit是F则最终为F -- 意味着不用处理 2.假如kiteAttr的isEdit是T: 2.1.假如fieldNameAndIsEdit的isEdit是空或T，最终为T
         * --意味着不用处理 2.2.假如fieldNameAndIsEdit的isEdit是F，最终为F
         */



        kiteAttrs.forEach(kiteAttr -> {

            // 百度地图的需求。需要做特殊处理
            if (Objects.nonNull(mapAidConfig)) {
                String provConfig = mapAidConfig.getCodea();
                if ((provConfig.contains(provinceCode) && KiteStringUtils.equalsAny(kiteAttr.getFieldName(), "2_0000211", "2_0000117"))) {
                    kiteAttr.setIsEdit("SF");
                }
            }
            // 如果当前IsEdit为SF，ST，则优先级最高，dc_public[2021092801]
            if (KiteStringUtils.equalsAny(kiteAttr.getIsEdit(), "SF", "ST")) {
                return;
            }
            if (KiteStringUtils.equalsAny(kiteAttr.getFieldName(),"2_0000087","2_0000065","2_0000066") && LocalKeyConsts.PROVINCE_ZHEJIANG.equals(opreatorProvinceNbr)){
                return;
            }
            // isEditScs是当前属性在service_control_scope中isEdit的值
            // 政企精品网只有变更才显示的属性 临时调速
            String isEditScs = KiteMapUtils.getString(fieldNameAndIsEdit, kiteAttr.getFieldName());
            if(KiteStringUtils.equalsAny(prodId, "60000418")&&"1091".equals(serviceOfferId)&&KiteListUtils.isEmpty(serviceOfferIdList)) {
                kiteAttr.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_E);
            }else if(KiteStringUtils.equalsAny(prodId, "60000418")&&"1091".equals(serviceOfferId)&&KiteListUtils.isNotEmpty(serviceOfferIdList)) {
                kiteAttr.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_D);
            }
            if (KiteStringUtils.equals(KeyConsts.IFTRUE_T, kiteAttr.getIsEdit())) {
                if (KiteStringUtils.equals(KeyConsts.IFTRUE_F, isEditScs)) {
                    kiteAttr.setIsEdit(KeyConsts.IFTRUE_F);
                    kiteAttr.setIsEditImg(KeyConsts.IFTRUE_F);
                }
            } else {
                if (KiteStringUtils.equals(KeyConsts.IFTRUE_T, isEditScs)) {

                    kiteAttr.setIsEdit(KeyConsts.IFTRUE_T);
                    kiteAttr.setIsEditImg(KeyConsts.IFTRUE_T);


                } else {
                    kiteAttr.setIsEditImg(KeyConsts.IFTRUE_F);
                }
            }
        });

        /*//互联网专线资料修正，端口带宽联动业务子类型和业务等级,资料修正：1080,升速或者降速
        if(KiteStringUtils.equals(prodId, "10002224")) {
            if(KiteListUtils.isNotEmpty(serviceOfferIdList)) {
                if(((serviceOfferIdList.contains("1020")||serviceOfferIdList.contains("1021")) && (serviceOfferIdList.contains("1020") || serviceOfferIdList.contains("1025"))) ||serviceOfferIdList.contains("1080")){
                    //获取端口带宽属性信息
                    List<KiteAttr> dkdkAttrList = inst.listAttrs().stream().filter(kiteAttr -> KiteStringUtils.equals("2_0000061",kiteAttr.getFieldName())).collect(Collectors.toList());
                    //获取业务子类型属性信息
                    List<KiteAttr> ywzlxAttrList = inst.listAttrs().stream().filter(kiteAttr -> KiteStringUtils.equals("200002072",kiteAttr.getFieldName())).collect(Collectors.toList());
                    //获取业务等级属性信息
                    List<KiteAttr> ywdjAttrList = inst.listAttrs().stream().filter(kiteAttr -> KiteStringUtils.equals("2_0000075",kiteAttr.getFieldName())).collect(Collectors.toList());

                    if(null != dkdkAttrList && dkdkAttrList.size()>0){
                        KiteAttr dkdkAttr = dkdkAttrList.get(0);
                        String dkdkValue= dkdkAttr.getValue();
                        if(KiteStringUtils.equalsAny(dkdkValue,"110009537","110009538","110009539")){
                            //如果端口带宽是这三个值，则业务等级和业务子类型不可编辑
                            if(null != ywzlxAttrList && ywzlxAttrList.size()>0){
                                KiteAttr ywzlxAttr = ywzlxAttrList.get(0);
                                ywzlxAttr.setIsEdit("F");
                            }
                            if(null != ywdjAttrList && ywdjAttrList.size()>0){
                                KiteAttr ywdjAttr = ywdjAttrList.get(0);
                                ywdjAttr.setIsEdit("F");
                            }
                        }
                    }
                }
            }
        }*/

        linkStyle(inst, kiteAttrs, sceneInstId, custId);

        // 放到对象池
        operateSceneInstService.setAttrs(sceneInstId, inst.getInstType(), inst.getInstId(), kiteAttrs);

        //互联网特殊处理勾选时产品属性之间的联动关系
        if(KiteStringUtils.equals(ProdCateUtil.getSingleProdId(ProdCateUtil.DIA_CODE), prodId)){
            if (KiteStringUtils.equals("1022", serviceOfferId)) {
                if(KiteStringUtils.isNotEmpty(opreatorProvinceNbr)&& KiteStringUtils.equals("51", opreatorProvinceNbr)){
                    this.dealNetProdAttr(prodId, serviceOfferId, kiteAttrs);
                }
            }
            if (KiteStringUtils.equals("1080", serviceOfferId) && LocalKeyConsts.PROVINCE_HEBEI.equals(opreatorProvinceNbr)) {
                KiteAttr bigBandWidthAttr = inst.getAttr("2_0000078"); // 是否大带宽
                KiteAttr bandWidthAttr = inst.getAttr("2_0000061");  // 端口带宽
                if (Objects.nonNull(bigBandWidthAttr) && KiteStringUtils.equals(bigBandWidthAttr.getValue(), "1_0000106") &&
                    CalculatePkgUsageUtil.compareWidth(bandWidthAttr.getValueDesc(), "1GBPS")) {
                    kiteAttrs.stream().filter(kiteAttr -> KiteStringUtils.equals(kiteAttr.getFieldName(), "2_0000078")).forEach(attr -> {
                        attr.setIsEdit(KeyConsts.IFTRUE_F);
                    });
                } else {
                    kiteAttrs.stream().filter(kiteAttr -> KiteStringUtils.equals(kiteAttr.getFieldName(), "2_0000078")).forEach(attr -> {
                        attr.setIsEdit(KeyConsts.IFTRUE_T);
                    });
                }
            }
            //浙江互联网 接入方式联动用户地址是否需要广播是否可编辑
            if (KiteStringUtils.equalsAny(serviceOfferId,"1010","1023" ) && LocalKeyConsts.PROVINCE_ZHEJIANG.equals(opreatorProvinceNbr)) {
                KiteAttr accessModeAttr = inst.getAttr("2_0000066"); // 接入方式
                KiteAttr isBroadAddrAttr = inst.getAttr("2_0000087");  // 用户地址是否需要广播
                if (Objects.nonNull(accessModeAttr) && Objects.nonNull(isBroadAddrAttr) && "100005455".equals(accessModeAttr.getValue()) && "1_0000107".equals(isBroadAddrAttr.getValue())){
                    kiteAttrs.stream().filter(kiteAttr -> KiteStringUtils.equals(kiteAttr.getFieldName(), "2_0000087")).forEach(attr -> {
                        attr.setIsEdit(KeyConsts.IFTRUE_F);
                    });
                }else {
                    kiteAttrs.stream().filter(kiteAttr -> KiteStringUtils.equals(kiteAttr.getFieldName(), "2_0000087")).forEach(attr -> {
                        attr.setIsEdit(KeyConsts.IFTRUE_T);
                    });
                }
            }
        }

        // 必填优先不需要，只需要按照orderId排序 UR：1713693
        List<ProdAttrVO> prodAttrList = kiteAttrs.stream()
            .filter(m -> !KiteStringUtils.equals(KeyConsts.PROD_ATTR_SHOW_TYPE_E, m.getShowType())).map(this::transform)
            .sorted(Comparator.comparing(this::orderIdToInt)).collect(Collectors.toList());


        prodAttrModule.setProdAttrList(prodAttrList);
        return prodAttrModule;
    }


    private void linkStyle(KiteProdInst kiteInst, List<KiteAttr> kiteAttrs, String sceneInstId, String custId) {
        String prodId = kiteInst.getSpecId();
        List<ObjAttrRstrRulDTO> rules;
        AttrData attrData = new AttrData();
        attrData.setCustId(custId);
        attrData.setSceneInstId(sceneInstId);
        for (KiteAttr kiteAttr : kiteAttrs) {
            AttrLinkageSource<?> linkageSource = new SameProdInstAttrSource(kiteInst, kiteAttr, attrData);
            rules = ProdAttrRstrRulCache.get(prodId, kiteAttr.getFieldName(),
                ObjAttrLinkageType.VALUE_LINK_STYLE.getCode(), true);
            GeneralAttrLinkageHandler.execAll(rules, linkageSource, Endpoint.A);
            rules = ProdAttrRstrRulCache.get(prodId, kiteAttr.getFieldName(),
                ObjAttrLinkageType.VALUE_LINK_STYLE.getCode(), false);
            GeneralAttrLinkageHandler.execAll(rules, linkageSource, Endpoint.Z);
        }
    }

    /**
     * {@link KiteAttr} to {@link ProdAttrVO}
     *
     * @param kiteAttr
     * @return
     */
    public ProdAttrVO transform(KiteAttr kiteAttr) {
        ProdAttrVO prodAttrVO = KiteBeanUtils.transform(kiteAttr, new ProdAttrVO());
        if (CollectionUtils.isNotEmpty(kiteAttr.getAttrValues())) {
            List<StaticAttrDO> staticAttrList = new ArrayList<>(kiteAttr.getAttrValues().size());
            kiteAttr.getAttrValues().forEach(kiteAttrValue -> {
                StaticAttrDO staticAttrDO = KiteBeanUtils.transform(kiteAttrValue, StaticAttrDO.class);
                staticAttrDO.setAttrValueDesc(kiteAttrValue.getAttrValueName());
                staticAttrList.add(staticAttrDO);
            });
            prodAttrVO.setAttrValues(staticAttrList);
        }
        return prodAttrVO;
    }

    private int orderIdToInt(ProdAttrVO v) {
        return Integer.parseInt(StringUtils.isEmpty(v.getOrderId()) ? "0" : v.getOrderId());
    }

    //互联网IP地址变更特殊处理方法
    private void dealNetProdAttr(String prodId, String serviceOfferId, List<KiteAttr> kiteAttrs) {
        if( kiteAttrs.size()>0 ) {
            for (KiteAttr prodAttr: kiteAttrs) {
                if(KiteStringUtils.equals("2_0000047", prodAttr.getFieldName()) && KiteStringUtils.equals("1_0000219", prodAttr.getValue())){
                    for (KiteAttr attrs: kiteAttrs) {
                        if(("210004178").equals(attrs.getFieldName())){
                            attrs.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_D);
                            attrs.setIsNull(KeyConsts.IFTRUE_F);
                        }
                    }
                }else if(KiteStringUtils.equals("2_0000047", prodAttr.getFieldName()) && KiteStringUtils.equals("1_0000220", prodAttr.getValue())){
                    for (KiteAttr attrs: kiteAttrs) {
                        if(("210004179").equals(attrs.getFieldName())){
                            attrs.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_D);
                            attrs.setIsNull(KeyConsts.IFTRUE_F);
                        }
                    }
                }else if(KiteStringUtils.equals("2_0000047",prodAttr.getFieldName()) && KiteStringUtils.equals("1_0000221", prodAttr.getValue())){
                    for (KiteAttr attrs: kiteAttrs) {
                        if(("210004178").equals(attrs.getFieldName())){
                            attrs.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_D);
                            attrs.setIsNull(KeyConsts.IFTRUE_F);
                        }
                        if(("210004179").equals(attrs.getFieldName())){
                            attrs.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_D);
                            attrs.setIsNull(KeyConsts.IFTRUE_F);
                        }
                    }
                }
                //张海东要按照1222重保优化需求来（不做隐藏）
              /*  // 当变更的省份为 广东是需要做隐藏处理
                if(("2_0000193").equals(prodAttr.getFieldName())){
                    prodAttr.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_H);
                }
                if(("2_0000194").equals(prodAttr.getFieldName())){
                    prodAttr.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_H);
                }
                if(("2_0000202").equals(prodAttr.getFieldName())){
                    prodAttr.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_H);
                }
                if(("2_0000203").equals(prodAttr.getFieldName())){
                    prodAttr.setShowType(KeyConsts.PROD_ATTR_SHOW_TYPE_H);
                }*/
            }
        }

    }

}
